﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Aribaccio;
using Aribaccio.Device;
using CommunityToolkit.Mvvm.ComponentModel;

namespace BDPAutodetect.Models
{
    /// <summary>
    /// 指标从机协议视图模型数据
    /// </summary>
    public partial class MTargetSlave : ObservableModel
    {
        /// <summary>
        /// 标识/编号
        /// </summary>
        public int ID { get; set; }

        /// <summary>
        /// 工位实例对象
        /// </summary>
        [ObservableProperty]
        protected MStation station;

        /// <summary>
        /// 从机设备实例
        /// </summary>
        [ObservableProperty]
        protected MSlave slave;

        /// <summary>
        /// 检测指标ID
        /// </summary>
        [ObservableProperty]
        protected MTarget target;

        /// <summary>
        /// 检测指标映射
        /// </summary>
        [ObservableProperty]
        protected MTarget targetMap;

        /// <summary>
        /// 发送指令（一般为ASCII）
        /// </summary>
        [ObservableProperty]
        protected string? slaveCommand;

        /// <summary>
        /// 校验指令（一般为ASCII）
        /// </summary>
        [ObservableProperty]
        protected string? checkCommand;

        /// <summary>
        /// 地址域/起始/头(一般为Modbus)
        /// </summary>
        [ObservableProperty]
        protected int slaveAddress;

        /// <summary>
        /// 功能码(一般为Modbus)
        /// </summary>
        [ObservableProperty]
        protected int slaveFuncCode;

        /// <summary>
        /// 寄存器地址/起始地址(一般为Modbus)
        /// </summary>
        [ObservableProperty]
        protected int registerAddress;

        /// <summary>
        /// 校验模式(一般为Modbus)
        /// </summary>
        [ObservableProperty]
        protected DeviceCheck checkMode;

        /// <summary>
        /// 数据类型（对应枚举类型，默认0 String）
        /// </summary>
        [ObservableProperty]
        protected DataType dataType;

        /// <summary>
        /// 数据单位（对应枚举类型，默认0 None）
        /// </summary>
        [ObservableProperty]
        protected DataUnit dataUnit;

        /// <summary>
        /// 显示单位（对应枚举类型，默认0 None）
        /// </summary>
        [ObservableProperty]
        protected DataUnit displayUnit;

        /// <summary>
        /// 数据单位精度(0表示无，非0表示单位转换值)
        /// </summary>
        [ObservableProperty]
        protected decimal dataPrecision;


        /// <summary>
        /// 发送等待标识状态（0 No，1 Yes）
        /// </summary>
        [ObservableProperty]
        protected ExecuteStatus sendWaitStatus;

        /// <summary>
        /// 检测通过等待标识状态（0 No，1 Yes）
        /// </summary>
        [ObservableProperty]
        protected ExecuteStatus detectWaitStatus;

        /// <summary>
        /// 检测许可标识状态（0 No，1 Yes）
        /// </summary>
        [ObservableProperty]
        protected ExecuteStatus permissionStatus;

        /// <summary>
        /// 构造函数
        /// </summary>
        public MTargetSlave(int argID, MStation argStation, MSlave argSlave, MTarget argTarget, MTarget? argTargetMap = null)
        {
            this.ID = argID;
            this.Station = argStation;
            this.Slave = argSlave;
            this.Target = argTarget;
            this.TargetMap = argTargetMap != null ? argTargetMap : new MTarget();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public MTargetSlave CloneDeep()
        {
            return new MTargetSlave(this.ID, this.Station, this.Slave, this.Target, this.TargetMap)
            {
                SlaveCommand = this.SlaveCommand,
                CheckCommand = this.CheckCommand,
                SlaveAddress = this.SlaveAddress,
                SlaveFuncCode = this.SlaveFuncCode,
                RegisterAddress = this.RegisterAddress,
                CheckMode = this.CheckMode,

                DataType = this.DataType,
                DataUnit = this.DataUnit,
                DisplayUnit = this.DisplayUnit,
                DataPrecision = this.DataPrecision,

                SendWaitStatus = this.SendWaitStatus,
                DetectWaitStatus = this.DetectWaitStatus,
                PermissionStatus = this.PermissionStatus
            };
        }

        /// <summary>
        /// 克隆数据表
        /// </summary>
        /// <returns></returns>
        public TTargetSlave CloneTData()
        {
            return new TTargetSlave()
            {
                ID = this.ID,
                StationID = this.Station.ID,
                SlaveID = this.Slave.ID,
                TargetID = this.Target.ID,
                TargetMapID = this.TargetMap.ID,
                Category = this.Target.TargetCategory.ToInt(),

                SlaveCommand = this.SlaveCommand,
                CheckCommand = this.CheckCommand,
                SlaveAddress = this.SlaveAddress,
                SlaveFuncCode = this.SlaveFuncCode,
                RegisterAddress = this.RegisterAddress,
                CheckMode = this.CheckMode.ToInt(),

                DataType = this.DataType.ToInt(),
                DataUnit = this.DataUnit.ToInt(),
                DisplayUnit = this.DisplayUnit.ToInt(),
                DataPrecision = this.DataPrecision,

                SendWaitFlag = this.SendWaitStatus.ToInt(),
                DetectWaitFlag = this.DetectWaitStatus.ToInt(),
                PermissionFlag = this.PermissionStatus.ToInt()
            };
        }

        /// <summary>
        /// 克隆设备指令
        /// </summary>
        /// <returns></returns>
        public ModbusSlave CloneDeviceSlave()
        {
            return new ModbusSlave(this.SlaveAddress, this.SlaveFuncCode, this.RegisterAddress, this.CheckMode);
        }

        public decimal GetDataUnitCoefficient()
        {
            switch (this.DataUnit)
            {
                case DataUnit.A:
                    return DisplayUnit == DataUnit.mA ? 1000 : 1;
                case DataUnit.mA:
                    return DisplayUnit == DataUnit.A ? 0.001m : 1;
                case DataUnit.V:
                    return DisplayUnit == DataUnit.mV ? 1000 : 1;
                case DataUnit.mV:
                    return DisplayUnit == DataUnit.V ? 0.001m : 1;
                case DataUnit.W:
                    return DisplayUnit == DataUnit.KW ? 0.001m : 1;
                case DataUnit.KW:
                    return DisplayUnit == DataUnit.W ? 1000 : 1;
                case DataUnit.C:
                default:
                    return 1;

            }
        }
    }
}
